home *** CD-ROM | disk | FTP | other *** search
/ The X-Philes (2nd Revision) / The X-Philes Number 1 (1995).iso / xphiles / hp48hor1 / phone.src < prev    next >
Text File  |  1991-01-23  |  23KB  |  624 lines

  1. %%HP: T(3)A(R)F(.);
  2. \<<  @ Start of Program @
  3. @ PHONE V1.4 by Joe Ervin.  18-JAN-1991 @
  4. @ NEW FEATURES FOR V1.4.
  5. @ Added handling of addresses, in addition to names and numbers.  
  6. @ Included YN menu definition, rather than using an external reference.
  7. @ Added RCLF and STOF to preserve the state of the system.  Also enforce
  8. @ STD display mode during execution.  Ensures a nice display during PHSEARCH.
  9. @
  10. @ NEW FEATURES FOR V1.3.   
  11. @ Added a PREV menu choice in the PHSEARCH routine to allow the user to
  12. @ move backwards through the list of matches.
  13.  
  14. CLEAR
  15. {} @ Dummy value to hold place for PHNAMES. @
  16. {} @ Dummy value to hold place for PHNUMBERS. @
  17. {}
  18. 0
  19. \-> PHNAMES PHNUMBERS ADDRESSES PHSIZE FLAGS
  20.    @ Creates local storage for names and numbers. @
  21.  
  22. \<< @ Surounds the procedures as well as main routine. @
  23.  
  24. \<<  @Start definition of PHSEARCH routine.@ 
  25. CLEAR
  26.  
  27. 0 0 0 {} 0 
  28.  
  29.  
  30. \-> 
  31.         SRCHNAME  @ Local variable to hold the search name. @
  32.         DONE      @ Local variable to detect when search has finished. @
  33.         MATCHNUM  @ Local variable to store the number of matches.  @
  34.         MATCHLIST     @ Stores list of matches. @
  35.         MATCHINDEX    @ Used to index into the match list. @
  36.  
  37.  
  38. @ What we are going to do now is to step through each name in the list, and @
  39. @ for each name, we will do a pattern match of the search name within each@ 
  40. @ name in the list. If the searchname is found within a given name, then @
  41. @ the index corresponding to the matched name will be added to MATCHLIST. @
  42. @ This routine uses flag 1 to indicate success or failure to the calling @
  43. @ routine. (SET = success, CLEAR = failure - i.e. no matches.  @ 
  44. @ Flag 2 is also used to indicate whether the main routine should exit @
  45. @ or prompt the user for another choice whether to search or edit the @
  46. @ phone list. @
  47.  
  48. \<< @This delimiter surrounds PHSEARCH's local variables@
  49. @ The following are definitions for four different menus which
  50. @ are used by the PHSEARCH facility.  These definitions are defined
  51. @ here as local variables for reasons of performace;  it ran
  52. @ kinda slow when I built these menus in real time.  Defining them
  53. @ here and then just calling them speeds things up considerably.
  54.  
  55. @ Here is the menu definition for MENADR @
  56.         {{"Next" \<< CONT \>> } {"Prev" \<<  \-> X
  57.         \<< CASE
  58.         'X==1' 
  59.           THEN 
  60.             IF 'MATCHNUM>1' @ Do nothing if only 1 match.  
  61.             THEN 
  62.               'MATCHNUM-1' EVAL CONT 
  63.             ELSE X CONT
  64.             END 
  65.           END 
  66.         'X==2' THEN MATCHNUM CONT END @ So next index will be 1.
  67.         'X-2' EVAL CONT  @ Do this by default to back up one index.
  68.         END  \>>  @ end of case statement 1.
  69.         \>> }                                
  70.         {} { "Addr" \<< 6 SF \-> X
  71.         \<< CASE
  72.         'X==1' THEN IF 'MATCHNUM>1' @ Do nothing if only 1 match.  
  73.           THEN 
  74.             'MATCHNUM' EVAL CONT 
  75.           ELSE X CONT
  76.           END 
  77.         END 
  78.         'X-1' EVAL CONT @ Do this by default to replay last index.
  79.         END \>> @ end of case statement 2.
  80.         \>>}
  81.         {} {"Exit" 
  82.         \<< 1 'DONE' STO CONT \>>} }
  83.  
  84. @ Here is the menu definition for MENNUM
  85.         {{"Next" \<< CONT \>> } {"Prev" \<<  \-> X
  86.         \<< CASE
  87.           'X==1' THEN IF 'MATCHNUM>1' @ Do nothing if only 1 match.  
  88.           THEN 
  89.             'MATCHNUM-1' EVAL CONT 
  90.           ELSE X CONT
  91.           END 
  92.         END 
  93.         @So next index will be MATCHNUM.
  94.         'X==2' THEN MATCHNUM CONT END @ So next index will be 1.
  95.         'X-2' EVAL CONT @ Do this by default to back up one index.
  96.         END \>> @ end of case statement 3.
  97.         \>> }                                
  98.         {} { "Num" \<< 6 CF \-> X
  99.         \<< CASE
  100.         'X==1' THEN IF 'MATCHNUM>1' @ Do nothing if only 1 match.  
  101.           THEN 
  102.             'MATCHNUM' EVAL CONT 
  103.           ELSE X CONT
  104.           END 
  105.         END 
  106.         'X-1' EVAL CONT @ Do this by default to replay last index.
  107.         END \>> @ end of case statement 4.
  108.         \>> } {} {"Exit" 
  109.         \<< 1 'DONE' STO CONT \>>} }
  110.  
  111. @ Here is the menu definition for MENPICKADR
  112.         {{"Next" \<< CONT \>> } {"Prev" \<<  \-> X
  113.         \<< CASE
  114.           'X==1' THEN IF 'MATCHNUM>1' @ Do nothing if only 1 match.  
  115.           THEN 
  116.             'MATCHNUM-1' EVAL CONT 
  117.           ELSE X CONT
  118.           END 
  119.         END 
  120.         'X==2' THEN MATCHNUM CONT END @ So next index will be 1.
  121.         'X-2' EVAL CONT @ Do this by default to back up one index.
  122.         END \>> @ end of case statement 5.
  123.         \>> }                   
  124.         {"Pick" 
  125.         \<<IF DUP 1 == THEN DROP MATCHNUM ELSE 1 - END GET 1 'DONE' STO 
  126.         4 CF CONT \>>} 
  127.         { "Addr" \<< 6 SF \-> X
  128.         \<< CASE
  129.         'X==1' THEN IF 'MATCHNUM>1' @ Do nothing if only 1 match.  
  130.           THEN 
  131.             'MATCHNUM' EVAL CONT 
  132.           ELSE X CONT
  133.           END 
  134.         END 
  135.         'X-1' EVAL CONT @ Do this by default to replay last index.
  136.         END \>> @ end of case statement 6.
  137.         \>>}
  138.         {} {"Exit" 
  139.         \<< 1 'DONE' STO 1 CF 2 SF CONT \>>} } 
  140.  
  141.  
  142. @ Here is the menu definition for MENPICKNUM
  143.         {{"Next" \<< CONT \>> } {"Prev" \<<  \-> X
  144.         \<< CASE
  145.           'X==1' THEN IF 'MATCHNUM>1' @ Do nothing if only 1 match.  
  146.           THEN 
  147.             'MATCHNUM-1' EVAL CONT 
  148.           ELSE X CONT
  149.           END 
  150.         END 
  151.         'X==2' THEN MATCHNUM CONT END @ So next index will be 1.
  152.         'X-2' EVAL CONT @ Do this by default to back up one index.
  153.         END \>> @ end of case statement 7.
  154.         \>> }                   
  155.         {"Pick" 
  156.         \<<IF DUP 1 == THEN DROP MATCHNUM ELSE 1 - END GET 1 'DONE' STO 
  157.         4 CF CONT \>>} 
  158.         { "Num" \<< 6 CF \-> X
  159.         \<< CASE
  160.         'X==1' THEN IF 'MATCHNUM>1' @ Do nothing if only 1 match.  
  161.           THEN 
  162.             'MATCHNUM' EVAL CONT 
  163.           ELSE X CONT
  164.           END 
  165.         END 
  166.         'X-1' EVAL CONT @ Do this by default to replay last index.
  167.         END \>> @ end of case statement 8.
  168.         \>> } {} {"Exit" 
  169.         \<< 1 'DONE' STO 1 CF 2 SF CONT \>>} } 
  170.  
  171. \->     MENADR       @ Menu definitions used within PHSEARCH.
  172.         MENNUM
  173.         MENPICKADR
  174.         MENPICKNUM
  175.  
  176.  
  177. \<< @ This delimeter surrounds the defining procedure for the above
  178.     @ menu definitions.
  179.  
  180. {} TMENU  @ Just to clear the menu from the main routine. @
  181. "Enter name..." {":Name:" \Ga} INPUT @Prompt user for name to search.@
  182.  
  183. IF DUP SIZE 6 \<=   @ If no name was entered. @ 
  184. THEN 
  185.  1 SF  @ To indicate successfull completion of search routine. @
  186.  2 SF  @ To cause the calling routine to ask again: SEARCH or EDIT.  @
  187.  4 CF @ Just in case this routine was called from PHEDIT. @
  188. ELSE
  189.   DUP SIZE 7 SWAP SUB 'SRCHNAME' STO
  190.   PHNAMES  OBJ\->@ Puts the list of names on the stack.@
  191.   IF SRCHNAME "*" SAME THEN 3 SF END
  192.   1 SWAP FOR I  @ Step through the whole list of names. @
  193.     SRCHNAME  @ Put the string to search for on the stack. @
  194.     IF POS 3 FS? OR 
  195.     @ If SRCHNAME exists anywhere within the name...@  
  196.     THEN
  197.       'MATCHNUM'  INCR DROP @ Add one to the number of matches. @
  198.       'PHSIZE - I + 1' EVAL 
  199.       'MATCHLIST' STO+  @ Add the match index to list of match indices. @
  200.     END  @ End this match check. @
  201.   NEXT   @ End loop checking for matches. @
  202.   3 CF
  203.  
  204.   IF MATCHNUM 0 \=/   @ IF there were at least some matches...@
  205.   THEN 
  206.     1 SF  2 CF   @ To indicate success to the calling routine. @
  207.     MATCHLIST 
  208.     1  @ To initialize index into matchlist. @
  209.     DO   @ Display list of matches until done. @
  210.       GETI  @ Fetch the next item pointed to by the matchindex. @ 
  211.       'MATCHINDEX' STO DUP 
  212.       IF 1 == THEN MATCHNUM ELSE DUP 1 - END
  213.       @ Now display which match we are looking at. @
  214.       CLLCD
  215.       "Match " SWAP + " of "  + MATCHNUM + 
  216.       1 DISP
  217.       ":Name:" PHNAMES MATCHINDEX GET + 
  218.       @ Concatenates label to name. @
  219.       "
  220. "
  221.       +  @ Adds a LF to the end of the NAME string.
  222.       IF 6 FC? @ If we are in "numbers" mode...
  223.       THEN
  224.         ":Number:" PHNUMBERS MATCHINDEX GET +  
  225.         @ Concatenates label to number. @
  226.         + @ Concatenates the NUMBER string to the NAME string.
  227.         4 DISP
  228.       ELSE 
  229.         "
  230. "
  231.         ADDRESSES MATCHINDEX GET +   
  232.         @ Concatenates label to address. @
  233.         + @ Concatenates the ADDRESS string to the NAME string.
  234.         3 DISP
  235.       END
  236.       3 FREEZE 
  237.  
  238. @ Now we need to call in the proper menu definition depending on what 
  239. @ display mode we are in (flag 6) and whether PHSEARCH was called from
  240. @ PHEDIT or from the main routine.
  241.       IF 4 FC?  @ PHSEARCH was called from main routine.
  242.       THEN 
  243.         IF 6 FC? @ If in "numbers" mode...
  244.         THEN  @ We need to add a menu item to switch to "addresses" mode.
  245.           MENADR
  246.         ELSE  @ We are in "address" mode...  
  247.           MENNUM
  248.         END
  249.       ELSE  @ PHSEARCH was called from PHEDIT.
  250.         IF 6 FC? @ If in "numbers" mode...
  251.         THEN  @ We need to add a menu item to switch to "addresses" mode.
  252.           MENPICKADR
  253.         ELSE     @ We are in "address" mode...  
  254.           MENPICKNUM
  255.         END
  256.       END
  257.  
  258.       TMENU HALT  @ Display the menu and stop for input.
  259.     UNTIL DONE
  260.     END
  261.   ELSE  @  If there were no matches...@
  262.     "The specified name
  263. was not found" @ To indicate search failure. @
  264.     1 CF 2 CF @ To indicate failure to the calling routine. @
  265.     CLLCD 1200 .1 BEEP 2 DISP 1 WAIT
  266.   END
  267. END
  268. \>> @ This delimeter surrounds the defining procedure for the 
  269.     @ menu definitions.
  270.  
  271. \>>
  272. \>> @Ends definition of PHSEARCH routine.@ 
  273.  
  274. \-> PHSEARCH @ Creates the subroutine PHSEARCH. @
  275. \<<
  276. \<< @ Definition of the PHEDIT routine starts here. @
  277. \-> P1 @ Take the parameter passed in on the stack. @
  278. \<< IF P1 "INT" SAME 
  279. THEN 
  280.  
  281. @ At this point, the local variables "PHNAMES" and "PHNUMBERS" contain the @
  282. @ names and numbers of the list to be edited.  Now we need to present the @
  283. @ user with a meaningful display from which to choose actions.  The actions @
  284. @ allowed include "MODIFY" and "ADD".  The following code prompts the user @
  285. @ to choose between these two options, and then performs the simple editing @
  286. @ function. @
  287.  
  288.     "Do you want to add
  289. to the list, modify
  290. an existing entry,
  291. or delete an entry?" 
  292.     CLLCD 1 DISP 3
  293.     FREEZE {{"Add" \<<"ADD" CONT\>>} {"Mdfy" \<<"MODIFY" 5 CF CONT\>>} 
  294.     {"Del"  \<<"MODIFY" 5 SF CONT \>>} {} {} 
  295.     {"EXIT" \<<2 SF CONT\>>}} TMENU HALT
  296.  
  297. ELSE CLEAR "ADD" @ This is for when PHEDIT was called by main with @
  298.                  @ P1 of "NEW". @
  299. END 
  300.  
  301. @ This is for the case when PHEDIT was called by the main routine for  @
  302. @ the case where there was no phone list. @
  303.  
  304. IF 2 FC?C 
  305. THEN 
  306.  
  307. {} TMENU  @ Clear the menu from what was previously there. @
  308. 0 0 0 0 \-> X TEMP LEN LEN2 DONE
  309. \<< CASE  
  310. @ Note the creation of the scratch variables 'TEMP', 'LEN', 'LEN2'.@
  311. @ 'TEMP' is scratch for the name, LEN is scratch for the name's length, @
  312. @ and 'LEN2' is scratch for the length of the phone number. @
  313. @ DONE is used for the repeat loop. @
  314. @ X gets the "ADD" or "MODIFY" string from the above prompt. @
  315.  
  316.   X "ADD" SAME @ Here we are adding to the list of names. @
  317.       THEN
  318.       DO 
  319.         "Enter name..." {":Name:" \Ga} INPUT 
  320.         @ Prompts the user to enter the name for this entry. @
  321.         @ Now we need to build up the command line for the INPUT command @
  322.         @ which will pull in the number for this entry.  We want to @
  323.         @ display the name above where the user is going to enter the @
  324.         @ number. @
  325.         DUP SIZE 'LEN' STO 'TEMP' STO 
  326.         IF LEN 6 > 
  327.         THEN 
  328.           "Enter number..." TEMP EVAL "
  329. :Number:" + { 2 9 }
  330.           \Ga 3 \->LIST INPUT 
  331.  
  332.           @ The current prompt shows the name and prompts for @
  333.           @ the phone number. @
  334.  
  335.           @ Now save the new information and update PHSIZE.
  336.           DUP DUP SIZE 'LEN2' STO 7 LEN SUB PHNAMES + 'PHNAMES' STO 
  337.           LEN 10 +
  338.           LEN2 SUB PHNUMBERS + 'PHNUMBERS' STO 
  339.           PHNAMES SIZE 'PHSIZE' STO
  340.  
  341.           @ Now we need to prompt for the address information...
  342.           "Enter address..." TEMP EVAL "
  343. :Addr:" + { 2 7 }
  344.           \Ga 3 \->LIST INPUT 
  345.  
  346.           @ The current prompt shows the name and prompts for @
  347.           @ the address. @
  348.  
  349.           @ Now save the new ADDRESS information.
  350.           DUP SIZE 'LEN2' STO 
  351.           LEN 8 +
  352.           LEN2 SUB ADDRESSES + 'ADDRESSES' STO 
  353.  
  354.         ELSE 
  355.           1 'DONE' STO
  356.         END
  357.       UNTIL DONE 
  358.       END
  359.     END  @"ADD"@
  360.  
  361.     X "MODIFY" SAME 
  362.       THEN         @ User wants to edit the list @
  363.  
  364.       CLEAR
  365.       0 0 ""  \-> INDEX  @ Stores the index of the entry to be edited. @
  366.                 DONE     @ Used to terminate DO UNTIL loop. @
  367.                 EDITSTRING   @ Stores the modified string. @
  368.  
  369. \<<
  370.       @ Basically what I want to do here is to call the PHSEARCH routine @
  371.       @ in a way that it will get the user to pick a specific entry.  @
  372.       @ I want to use the PHSEARCH routine to do this since so much of @
  373.       @ the code needed to do this is alread done.  The result of the @
  374.       @ PHSEARCH routine is to return an index indicating the exact @
  375.       @ entry which is to be edited.  This routine then needs only @
  376.       @ display it in an input statement in such a way that the user @
  377.       @ can modify it as it sits on the display.  When the user presses @
  378.       @ ENTER, the modified entries (name and number) will be written @
  379.       @ back into the database. @
  380.       @ This routine also checks flag 5 to determine whether the user @
  381.       @ wants to delete the record or simply modify it. @
  382.  
  383.       DO 
  384.         2 CF 4 SF PHSEARCH EVAL @ Get the index of entry to be modified. @
  385.       UNTIL 1 FS?C @ Repeat search routine until user selects an entry @
  386.                    @ or gives up. @
  387.       END  
  388.       4 CF   @ Flag 4 was set only to indicate to PHSEARCH to use "pick" in @
  389.                 @ the menu so user could choose the item to edit.
  390.       IF 2 FC?C  @ If flag 2 is set, then the user must have given up @
  391.                  @ trying to select an entry to edit. @
  392.       THEN  @ Let's edit the selected entry @
  393.       'INDEX' STO 
  394.         IF 5 FC?C 
  395.         THEN 
  396.           DO 
  397.   @ This section of code was modified in v1.4 to handle the editing of 
  398.   @ addresses.  For this reason, I use several IFTE commands below to 
  399.   @ differentiate between editing the PHNUMBERS field and the 
  400.   @ ADDRESSES field. 
  401.  
  402.             INDEX DUP 
  403.             PHNAMES SWAP GET @ Gets the name to be modified. @
  404.             SWAP 
  405.             6 FC? 'PHNUMBERS' 'ADDRESSES' IFTE 
  406.             @ Gets PHNUMBERS or ADDRESSES, depending on the 
  407.             @ state of flag 6.
  408.  
  409.             SWAP GET   @ Gets number/address to be modified. @
  410.  
  411.             @ The stack now has
  412.             @           2: name
  413.             @           1: number/addr
  414.  
  415.             @ Now reformat the information for the INPUT command.
  416.  
  417.             6 FC? ":Number:" ":Addr:" IFTE 
  418.             SWAP +
  419.             SWAP ":Name:" SWAP +   @ Adds tags to the name and num/addr.
  420.             "
  421. "
  422.             + SWAP +  @ Creates one long string with a carraige return @
  423.             @ to separate the name and num/addr strings. @
  424.  
  425.  
  426.             @ Now display this information using INPUT so the user can @
  427.             @ edit the strings. @
  428.  
  429.  
  430.             "Edit entry..."  SWAP 0
  431.             2 \->LIST {} TMENU INPUT
  432.  
  433.             @ At this point, the user has been prompted with the name and @
  434.             @ number to be modified.  The keyboard is in overstrike mode @
  435.             @ and the cursor was left at the end of the number. @
  436.  
  437.             @ Now we must recover the new name and number from the @
  438.             @ string on the stack. @
  439.  
  440.             DUP 'EDITSTRING' STO   @ Save a copy of the string.
  441.             IF DUP ":Name:" POS 1 ==   @ Test for existence of the name...
  442.             SWAP DUP 
  443.             6 FC? ":Number:" ":Addr:" IFTE 
  444.             POS                   @ ...and number tags within the string.
  445.             DUP 'TEMP' STO  @ Save location of num/addr tag.
  446.             ROT AND    
  447.             THEN    @ The user entered valid data. @
  448.  
  449.               @ Update the database with new name.@
  450.               DUP 7 TEMP 2 - SUB @ Extract the modified name. @
  451.               1 \->LIST PHNAMES SWAP INDEX SWAP REPL
  452.               'PHNAMES' STO    @ Save modified name in PHNAMES. 
  453.  
  454.               @ Update the database with the new number/address.
  455.               TEMP 
  456.               6 FC? 8 6 IFTE 
  457.               + EDITSTRING SIZE SUB @ Extract the new name/addr.
  458.               1 \->LIST
  459.               6 FC? 'PHNUMBERS' 'ADDRESSES' IFTE 
  460.               SWAP INDEX SWAP REPL 
  461.               6 FC? "'PHNUMBERS'" "'ADDRESSES'" IFTE 
  462.               OBJ\-> STO 
  463.  
  464.               1 'DONE' STO 
  465.               CLEAR
  466.             ELSE CLLCD 1200 .1 BEEP "Invalid Entry" 2 DISP 2 WAIT
  467.             END
  468.           UNTIL DONE
  469.           END
  470.         ELSE    @ The user wants to delete the entry.  @
  471.           CLEAR INDEX DUP 
  472.           PHNAMES SWAP GET @ Gets the name to be modified. @
  473.           SWAP PHNUMBERS SWAP GET   @ Gets number to be modified. @
  474.  
  475.           @ The stack now has           @
  476.           @                   2: name   @
  477.           @                   1: number @
  478.  
  479.           @ Now reformat the information for the INPUT command. @
  480.  
  481.           ":Number:" SWAP +
  482.           SWAP ":Name:" SWAP +   @ Adds tags to the name and number. @
  483.           "
  484. "
  485.           + SWAP +  @ Creates one long string with a carraige return @
  486.           @ to separate the name and number strings. @
  487.  
  488.  
  489.           @ Now display this information and prompt user to verify that @
  490.           @ this record should be deleted.   
  491.  
  492.           CLLCD  "Delete entry?"  1 DISP
  493.           4 DISP 1200 .1 BEEP 3 FREEZE 
  494.           { { "Yes" \<< 1 CONT \>> } { } { } { } { } 
  495.           { "No" \<< 0 CONT \>> } }
  496.           TMENU HALT
  497.           IF   @ yes @
  498.           THEN 
  499.             PHNAMES  OBJ\->  DROP @ Put the list of names on the stack. @
  500.             PHSIZE INDEX 1 - - ROLL 
  501.             DROP   @ Deletes the entry pointed to by INDEX. @
  502.             PHSIZE 1 - \->LIST 'PHNAMES' STO  
  503.  
  504.             PHNUMBERS  OBJ\->  DROP @ Put the list of names on the stack. @
  505.             PHSIZE INDEX 1 - - ROLL 
  506.             DROP  @ Deletes the entry pointed to by INDEX. @
  507.             PHSIZE 1 - \->LIST 'PHNUMBERS' STO  
  508.  
  509.             ADDRESSES  OBJ\->  DROP @ Put the list of names on the stack. @
  510.             PHSIZE INDEX 1 - - ROLL 
  511.             DROP  @ Deletes the entry pointed to by INDEX. @
  512.             'PHSIZE'  DECR \->LIST 'ADDRESSES' STO  
  513.           END
  514.         END
  515.       ELSE 5 CF 
  516.       END
  517. \>>
  518.     END
  519.   END  
  520. \>>    @end case@
  521. END  @IF 2 FC?C
  522.  
  523. ADDRESSES PHNUMBERS PHNAMES 3 \->LIST 'PHDAT' STO
  524.  
  525.  
  526. \>> @ Surrounds PHEDIT's parameters. @
  527. \>> @ Ends the definition of PHEDIT and pushes PHEDIT on the stack @
  528.     @ to be defined later.@
  529.  
  530.  
  531.  
  532.  
  533.  
  534.  \-> PHEDIT @ Defines the subroutine "PHEDIT", which edits the database. @
  535.            @ PHEDIT takes as parameters a single string which must have the @
  536.            @ value "NEW", indicating a new list should be created, @
  537.            @ or "INT", indicating the old list should be prompted as to 
  538.            @ whether the current list is to be added to or edited. @
  539.  
  540. \<< @ The main routine starts here. @
  541. 64 STWS  @ Sets the word size to 64.  Needed for RCLF
  542. RCLF DUP 'FLAGS' STO
  543. 2 {#0d} REPL STOF  @ Clear user flags.
  544. STD  @ Set display to STD mode.  Looks nicer.
  545. IF 'PHDAT' VTYPE -1 ==   
  546.   THEN
  547.   CLLCD 
  548.   "Phone Database does" 2 DISP "not exist.  Do you"
  549.   3 DISP "want to create it?"
  550.   4 DISP 3 FREEZE 
  551.   { { "Yes" \<< 1 CONT \>> } { } { } { } { } 
  552.   { "No" \<< 0 CONT \>> } }
  553.   TMENU HALT  @ Prompt the user for yes/no @
  554.   IF 
  555.     THEN  
  556.     {} DUP 'PHNAMES' STO 'PHNUMBERS' STO 
  557.     "NEW" PHEDIT  EVAL @ tells PHEDIT to go directly to the @
  558.                              @ edit input mode on a new list @
  559.   @ After the user exits PHEDIT, control falls down to main routine below.@
  560.     ELSE
  561.  
  562. "You must create a
  563. phone database before
  564. any further action can
  565. be taken."
  566.       2 DISP CLEAR 2 MENU  1200 .1 BEEP 3 FREEZE  3 WAIT
  567.       0 DOERR         @ Obviously, the user is a pinhead. @
  568.     END 
  569.  
  570.   END 
  571.  
  572. @ We need to start the main routine.@
  573. 0 \-> DONE \<<
  574.   @ First we need to suck in the database. @
  575.      {} DUP 'PHNAMES' STO 'PHNUMBERS' STO 
  576.   CLEAR  @ Clear the stack, so the following DEPTH command will work.
  577.   PHDAT EVAL
  578.  
  579. @ At this point, we need to determine if the current database is in
  580. @ the new format used with V1.4 and later.  If the database does not 
  581. @ contain the list of ADDRESSES, then we need to add them and write it back
  582. @ out.
  583.   IF  DEPTH 2 == 
  584.   THEN @ We must update the database structure.
  585.     CLLCD "Reformating PHDAT.
  586. Please wait..." 2 DISP 1 WAIT
  587.     DUP @ Create a spare copy of PHNAMES.
  588.     {}  @ Put a null list on the stack.
  589.     SWAP SIZE 1 SWAP FOR I "" + NEXT  @ Creates a list of null strings.
  590.     3 ROLLD 3 \->LIST
  591.     'PHDAT' STO @ Adds the empty address list to the database.
  592.     CLEAR PHDAT EVAL
  593.   END    
  594.  
  595.   'PHNAMES' STO  'PHNUMBERS' STO @ copies the database in the local  @
  596.                                  @ variables 'PHNAMES' , 'PHNUMBERS' @
  597.   'ADDRESSES' STO                @ and 'ADDRESSES'.
  598.   PHNAMES SIZE 'PHSIZE' STO  @ Indicates the number of names in the list. @
  599.  
  600.   DO 
  601.   @ Here we want to ask the user whether we are searching or editing. @
  602. "Do you want to 
  603. search the list or
  604. edit the list?" 
  605.   CLLCD 1 DISP 3 FREEZE
  606.   {{"SRCH" \<< DO PHSEARCH EVAL UNTIL 1 FS?C END CONT \>>}
  607.   {"EDIT" \<< "INT" PHEDIT  EVAL CONT \>>} 
  608.   {} 
  609.   {} {} {"Exit" \<<1 'DONE' STO CONT \>>}} TMENU HALT
  610.   @ "INT" for PHEDIT here to tell PHEDIT to prompt the user as to @
  611.   @ whether he wants to edit (modify) the phone list or simply add to it. @
  612.  
  613.   UNTIL DONE @ Keep on doing this loop until DONE. @
  614.   END
  615.   \>> @ DO @
  616.  
  617.   CLEAR 2 MENU 
  618.   FLAGS STOF  @ Resets the state of the system and user flags.
  619. \>> @ Defines bounds for which PHSEARCH is defined. 
  620. \>> @ Main Routine. 
  621. \>> @ Main routine and procedures. 
  622. \>> @ End of Program. 
  623.